﻿using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Xml.Linq;
using static Dapper.SqlMapper;


namespace HBase {//

    public abstract class AbsBaseServer :IBaseServer {
        
        protected abstract IDbConnection getConnection(string key);
        abstract public GKDBType getGKDBType();
        public Page<T> queryPage<T>(string key,string sql ,string orderBy ,PageDto param) {
            if( param == null || param.pageSize == -1 ) {
                List<T> list = getConnection(key).Query<T>(sql + " order by " + orderBy ,param).ToList<T>();
                Page<T> p = new Page<T>();
                p.content = list;
                return p;
            }
            int start = 0, end = 20;
            if( param != null ) {
                start = (param.pageNum - 1) * param.pageSize + 1;
                end = start + param.pageSize - 1;
            }
            if( string.IsNullOrEmpty(sql) ) {
                return null;
            }
            if( (start <= 0 && end <= 0) ) {
                return null;
            }
            sql = PageDialect.pageSql(getGKDBType() ,sql ,start ,end ,orderBy);
            Page<T> page = getConnection(key).QueryMultiple<T>(sql ,param);
            return page;
        }
        public List<T> GetAll<T>(string key, string whereStr = null ,object param = null) where T : class {
            IDbConnection con = getConnection(key);
            List<T> list = con.GetAll<T>(whereStr ,param ,null);
            return list;
        }
        public List<T> getAll<T>(string key, string tableName ,string whereStr = null ,object param = null ,string orderField = "") where T : class {
            string sql = "select * from " + tableName + " where 1=1 " + whereStr;
            if( !String.IsNullOrWhiteSpace(orderField) ) {
                sql += " order by " + orderField;
            }
            return getConnection(key).Query<T>(sql ,param)
                .ToList();
        }
        public List<T> GetField<T>(string key, string fields ,string where = null ,object param = null) where T : class {
            return getConnection(key).getField<T>(fields ,where ,param);
        }
        public long insert (string key, object t)   {
            return getConnection(key).Insert(t);
        }
        public long insert(string key, string name, object t) {
            return getConnection(key).Insert(name,t);
        }
        public List<T> GetEntities<T>(string key, string sql ,string connStr = "" ,params SqlParameter[] parameters) {
            var dp = new DynamicParameters();
            if( parameters != null && parameters.Length > 0 ) {
                foreach( SqlParameter pt in parameters ) {
                    dp.Add(pt.ParameterName ,pt.Value ,pt.DbType);
                }
            }
            var result = getConnection(key).Query<T>(sql ,dp);
            return result.ToList();
        }

        public void runProcedure(string key, string proc, params SqlParameter[] parameters) {
            var dp = new DynamicParameters();
            if (parameters != null && parameters.Length > 0) {
                foreach (SqlParameter pt in parameters) {
                    dp.Add(pt.ParameterName, pt.Value, pt.DbType, pt.Direction);
                }
            }
            getConnection(key).RunProcedure(proc, dp);
            if (parameters != null && parameters.Length > 0) {
           
                 foreach (SqlParameter pt in parameters) {
                    if (pt.Direction == ParameterDirection.Output || pt.Direction == ParameterDirection.InputOutput) {
                        if (pt.SqlDbType == SqlDbType.BigInt) {

                            var v = dp.Get<long>(pt.ParameterName);
                            pt.Value= v;
                        }
                       
                    }
                   
                }

            }
        }
        public T getById<T>(string key, long id ,IDbTransaction transaction = null) where T : class {
            return getConnection(key).GetById<T>(id ,transaction);
        }
        public T getById<T>(string key, string tableName, long id, IDbTransaction transaction = null) where T : class {
            return getConnection(key).GetById<T>(tableName,id, transaction);
        }
        public long insertNotNull<T>(string key, T t) where T : class {
            return getConnection(key).InsertNoNull<T>(t);
        }
        public bool updateNotNull<T>(string key, T t) where T : class {
            return getConnection(key).updateNotNull(t);
        }
        public bool update<T>(string key, T t) where T : class {
            return getConnection(key).Update(t);
        }

        public bool update<T>(string key, String tableName, T t) where T : class {

            return getConnection(key).Update(tableName,t);
        }
        public void delete<T>(string key, long id) where T : class {
            getConnection(key).Delete<T>(id);
        }
        public void delete(string key, BaseEntity e) {
            
            getConnection(key).delete(e);

        }
        public void executeSql(string key, string sql, object obj)  {

            
            var deleted = getConnection(key).Execute(sql, obj);


        }
        public void delete<T>(string key, string where ,object obj) where T : class {

            Type type = typeof(T);
            var name = ToStr.GetTableName(type);
            var statement = String.Format("delete from {0} where {1} " ,name ,where);
            var deleted = getConnection(key).Execute(statement ,obj);


        }

        public void insertAll<T>(string key, List<T> t) where T : class {
            getConnection(key).BatchInsert(t);
        }

       
    }
}
